package IceAssembly;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

/**
 * This class controls the flow of the program.<p>
 * <u>Member Variables:</u><br>
 *  code_string : private static String[]<br>
 *  location_counter : public static int<br>
 * Change Log:
 *  April 14,2008 - Initial code entry - Aashish Kumar.<br>
 *  April 22,2008 - no longer extends convet.java - added by mistake - Aashish Kumar.<br>
 *  April 22,2008 - checkLineErrors() member function no longer exits - Aashish Kumar.<br>
 * <p>
<b>Original Author:</b> Yogesh Jindal
<p>
 */
public class Control{
    
    public static String[] code_string = new String[0];
    public static int location_counter;
    public static int line_num;
    public static String debug_status = "OFF";
    public static String internal_debug = "ON"; //paths to files will change, set to OFF when grading. Set to ON when coding and to TESTCASES when checking testcases.
    public static String code_file = "DefaultCode.txt";
    public static String link_mot="tables//MOT.csv";
    public static String link_pot="tables//POT.csv";
    public static String link_errortable="tables//ERRORTABLE.txt";
    public static String name_of_test = "Default";
    public static String version_number = "SP2";
    public static String revision_number = "beta2";
    
    /**
     * This function initializes code_string[] from the code file
     * whose URL String is declared in the Interface.java.<p>
     * Change Log:<br>
     *  4/16/08 - Initial Code Entry - Aashish Kumar<p>
     * Errors produced:<br>
     * None<p>
     * Date of module being installed: 4/16/08
     * <p>
     *   <b>Original Author:</b> Aashish Kumar
     * <p>
     * @return Returns 1 if successful else returns 0.
     */
    private int getCodeFile () {
        try{
            File file = new File(code_file);
            BufferedReader buffer_reader = new BufferedReader(new FileReader(file));
            int no_lines=0;
            while(buffer_reader.readLine()!=null){
               no_lines++;
            }
            code_string = new String[no_lines]; 
            buffer_reader = new BufferedReader(new FileReader(file));
            int index=0; String temp;
            while((temp=buffer_reader.readLine())!=null){
                code_string[index]= temp; index++;
            }
        }catch(IOException e){
            System.out.println("file reading exception from Control.java.getcodefile(); function");
            return 0;
        }
        return 1;
    }
    
    /**
     * This function reads the lines in the code_string[],
     * it then remove the comments and optimize the spaces
     * and then tokenizes the string and calls the process
     * instruction function...<p>
     * Change Log:<br>
     *  4/16/08 - Initial Code Entry - Aashish Kumar<br>
     *  5/11/08 - Blank line warning after end removed. - Yogesh Jindal.<br>
     * Errors produced:<br>
     * None<p>
     * Date of module being installed: 4/16/08
     * <p>
<b>Original Author:</b> Aashish Kumar
<p>
    **/
    private int readLine () {      
        Convert convert_instance = new Convert();
        Tokenize tokenize_instance = new Tokenize();
        Process process_instance = new Process();                
        Table table_instance = new Table();
        for(line_num=0; line_num<code_string.length; line_num++){
            if(location_counter>=1024){
                if(table_instance.addToErrorTable("006")==0){
                    return 1000;
                }
                return 500;
            }            
            String temp = code_string[line_num];            
            temp = convert_instance.getNonCommentString(temp);
            temp = convert_instance.optimizeTheSpaces(temp);
            if(temp.compareTo("")==0 || temp.compareTo(" ")==0){
                if(line_num==0){//a blank line or a comment line
                    table_instance.addToErrorTable("001");//fatal error
                    return 4000;
                }
            }else{
                String[] tokened_string= tokenize_instance.tokenize(temp);
                int ret_value = process_instance.processInstruction(tokened_string);
                if(ret_value==1000){                    
                    return 1000;
                }else if(ret_value==2000){                    
                    return 2000;
                }else if(ret_value==50){
                    //everything was fine or errors were handled
                }else if(ret_value==5){                     
                    line_num++;
                    while(line_num<code_string.length){
                        code_string[line_num] = code_string[line_num].replace(" ", "");
                        if(!code_string[line_num].contentEquals("")){
                            table_instance.addToErrorTable("210");                            
                        }
                        line_num++;
                    }
                    return 5;
                }else if(ret_value==4000){
                    return 4000;
                }
            }    
        }
       return 6;
    }
    
    /**
     * This function sets the testing mode parameters.<p>
     * Modified Log: None.<br>
     * Error Condition tested: None.<br>
     * Creation Date : May 17,2008.<br>
     * <p><b>Original Author:</b> Yogesh Jindal.
     * @return void
     */
    private void setTestingParameters(){
        link_mot="src//IceAssembly//MOT.csv";
        link_pot="src//IceAssembly//POT.csv";
        link_errortable="src//IceAssembly//ERRORTABLE.txt";
    }
    
    /**
     * This function sets the internal debugging mode parameters.<p>
     * Modified Log: None.<br>
     * Error Condition tested: None.<br>
     * Creation Date : May 17,2008.<br>
     * <p><b>Original Author:</b> Yogesh Jindal.
     * @return void
     */
    public void setInternalDebuggingParameters(){
        code_file = "src//CODE.txt";
        link_mot="src//IceAssembly//MOT.csv";
        link_pot="src//IceAssembly//POT.csv";
        link_errortable="src//IceAssembly//ERRORTABLE.txt";
        
        Table.link_error_file = new File("src//error_file.txt");
        Table.link_inter_file = new File("src//inter_file.txt");
        Table.link_symbol_file = new File("src//symbol_file.txt");

        ObjectFile.ObjectFile.link_object_file = new File("src//object_file.txt");
        ObjectFile.SourceListing.link_sourcelisting_file = new File("src//sourcelisting.txt");
    }
    
    /**
     * This function sets the external debugging mode parameters.<p>
     * Modified Log: None.<br>
     * Error Condition tested: None.<br>
     * Creation Date : May 17,2008.<br>
     * <p><b>Original Author:</b> Yogesh Jindal.
     * @return void
     * @param file_name
     */
    private void setExternalDebuggingParameters(String file_name){
        code_file = file_name;
        link_mot="tables//MOT.csv";
        link_pot="tables//POT.csv";
        link_errortable="tables//ERRORTABLE.txt";
        
        Table.link_error_file = new File("out//error_file_"+file_name);
        Table.link_inter_file = new File("out//inter_file_"+file_name);
        Table.link_symbol_file = new File("out//symbol_file_"+file_name);
        
        ObjectFile.ObjectFile.link_object_file = new File("out//obj_file_"+file_name);
        ObjectFile.SourceListing.link_sourcelisting_file = new File("out//src_listing_"+file_name);
    }
    
    /**
     * The main will read the file whose url is in the Interface.java.
     * Command line file reading still needs to be done.<p>
     * Change Log:<br>
     *  4/16/08 - Initial Code Entry - Aashish Kumar<p>
     * Errors produced:<br>
     * None<p>
     * Date of module being installed: 4/16/08
     * <p>
<b>Original Author:</b> Aashish Kumar
<p>
     * @param args takes the input file from command line(may be)...
     */
    public static void main(String[] args){
        Control control_instance = new Control();
        if(internal_debug.contentEquals("ON")){
            control_instance.setInternalDebuggingParameters();
        } else if(internal_debug.contentEquals("TESTCASES")){
            control_instance.setTestingParameters();
        } else if(internal_debug.contentEquals("OFF")){
            if(args.length==0){
                control_instance.setExternalDebuggingParameters("Default.txt");
            }else{
                control_instance.setExternalDebuggingParameters(args[0]);
            }
        }
        Initialize initialize_instance = new Initialize();//don't move this line up
        Table table_instance = new Table();
        control_instance.getCodeFile();
        int value=0;
        try {
            value = control_instance.readLine();
        } catch (Exception exception) {
            value = -100;
        }
        if(value==500){
            table_instance.addToErrorTable("006");
        }
        if(value==6){
            table_instance.addToErrorTable("005");
        }
        if(value==2000){
            table_instance.addToErrorTable("003");
        }
        table_instance.sortSymbolTable();
        table_instance.addToSymbolFile();
        table_instance.addToInterFile();
        table_instance.addToErrorFile();
    }
}